﻿using DroneLib;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading;
using System.Xml.Linq;
using static MAVLink;

namespace DroneLib.Vehicles
{
    partial class Vehicle
    {
        delegate void MessageProcessMethod(MAVLinkMessage message);

        Dictionary<MAVLINK_MSG_ID, Func<MAVLinkMessage, bool>> _MessageProcessMethods = new Dictionary<MAVLINK_MSG_ID, Func<MAVLinkMessage, bool>>();
        protected virtual void LoadMessageProcessMethods()
        {
            Dictionary<string, MAVLINK_MSG_ID> methodNames = new Dictionary<string, MAVLINK_MSG_ID>();
            foreach (MAVLINK_MSG_ID msgId in Enum.GetValues(typeof(MAVLINK_MSG_ID)))
            {
                methodNames.Add($"ProcessMessage_{msgId}", msgId);
            }

            Type type = this.GetType();
            foreach (MethodInfo mi in type.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance))
            {
                string miName = mi.Name;
                if (methodNames.ContainsKey(miName))
                {
                    try
                    {
                        var func = (Func<MAVLinkMessage, bool>)mi.CreateDelegate(typeof(Func<MAVLinkMessage, bool>), this);
                        _MessageProcessMethods.Add(methodNames[mi.Name], func);
                        //_MavStream.SubscribeMessage(methodNames[mi.Name], func, this.SysId, MAV_COMPONENT.MAV_COMP_ID_AUTOPILOT1);
                        _MavStream.SubscribeMessage(methodNames[mi.Name], ProcessMessage, this.SysId, MAV_COMPONENT.MAV_COMP_ID_AUTOPILOT1);
                    }
                    catch (Exception ex)
                    {

                    }
                }
            }
            

            if (_ThdSystemInfoPump == null)
            {
                _ThdSystemInfoPump = new Thread(SystemInfoPump) { IsBackground = true };
                _ThdSystemInfoPump.Start();
            }
        }

        //object _ExternalMessageProcessMethodsLock = new object();
        //Dictionary<MAVLINK_MSG_ID, Func<MAVLinkMessage,bool>> _ExternalMessageProcessMethods = new Dictionary<MAVLINK_MSG_ID, Func<MAVLinkMessage, bool>>();
        //public void RegisterExternalProcessMethod(params (MAVLINK_MSG_ID msgId, Func<MAVLinkMessage, bool> processMethod)[] processMethods)
        //{
        //    if (processMethods.Length == 0)
        //        throw new ArgumentException("消息处理方法的数量不能为0");

        //    foreach (var item in processMethods)
        //    {
        //        //if (_ExternalMessageProcessMethods.ContainsKey(item.Item1) == false)
        //        //    _ExternalMessageProcessMethods.Add(item.Item1, item.Item2);
        //        //else
        //        _ExternalMessageProcessMethods[item.msgId] = item.processMethod;
        //    }
        //}

        public int SubscribeMessage(MAVLink.MAVLINK_MSG_ID msgId, Func<MAVLink.MAVLinkMessage, bool> function)
        {
            return _MavStream.SubscribeMessage(msgId, function, this.SysId, MAVLink.MAV_COMPONENT.MAV_COMP_ID_AUTOPILOT1);
        }

        public void UnsubcribeMessage(int id)
        {
            _MavStream?.UnsubcribeMessage(id);
        }

        //public void UnregisterExternalProcessMethod(params MAVLINK_MSG_ID[] msgIds)
        //{
        //    //Console.WriteLine("Locking _ExternalMessageProcessMethodsLock for unregister");
        //    lock (_ExternalMessageProcessMethodsLock)
        //    {
        //        //Console.WriteLine("_ExternalMessageProcessMethodsLock locked for unregister");
        //        foreach (MAVLINK_MSG_ID msgId in msgIds)
        //        {
        //            if (_ExternalMessageProcessMethods.ContainsKey(msgId))
        //            {
        //                _ExternalMessageProcessMethods.Remove(msgId);
        //            }
        //        }
        //    }
        //}

        public bool ProcessMessage(MAVLinkMessage msg)
        {
            if (msg.sysid != this.SysId)
                return false;

            MAVLINK_MSG_ID msgId = (MAVLINK_MSG_ID)msg.msgid;

            //if(_ExternalMessageProcessMethods.ContainsKey(msgId))
            //{
            //    Func<MAVLinkMessage,bool> act = null;
            //    //Console.WriteLine("Locking _ExternalMessageProcessMethodsLock for message process");
            //    lock (_ExternalMessageProcessMethodsLock)
            //    {
            //        //Console.WriteLine("_ExternalMessageProcessMethodsLock locked for message process");
            //        if (_ExternalMessageProcessMethods.ContainsKey(msgId))
            //            act= _ExternalMessageProcessMethods[msgId];
            //    }
            //    act?.Invoke(msg);
            //    return true;
            //}
            //else
            if (_MessageProcessMethods.ContainsKey(msgId))
            {
                //Console.WriteLine((MAVLINK_MSG_ID)msg.msgid);
                //MethodInfo mi = _MessageProcessMethods[(MAVLINK_MSG_ID)msg.msgid];
                //mi.Invoke(this, new object[] { msg });
                
                Func<MAVLinkMessage, bool> func= _MessageProcessMethods[(MAVLINK_MSG_ID)msg.msgid];
                func.Invoke(msg);
                return true;
            }

            return false;
        }



        Thread _ThdSystemInfoPump;
        protected void SystemInfoPump()
        {
            while(true)
            {
                if(messages.Count==0)
                {
                    Thread.Sleep(10);
                    continue;
                }

                var msg = messages[0];
                messages.RemoveAt(0);

                SystemInfoReceived?.Invoke(this, msg.time,  msg.message, msg.severity);
            }
        }

        protected bool ProcessMessage_HEARTBEAT(MAVLinkMessage msg)
        {
            mavlink_heartbeat_t hb = (mavlink_heartbeat_t)msg.data;

            MAV_TYPE type = (MAV_TYPE)hb.type;
            if (type != this.Type)  // CubeOrange有ADSB的心跳过来，并且其SYSID也为1……
                return false;

            var newarmed = (hb.base_mode & (byte)MAV_MODE_FLAG.SAFETY_ARMED) ==
                                        (byte)MAV_MODE_FLAG.SAFETY_ARMED;

            if (newarmed != this.Armed)
            {
                this.Armed = newarmed;
            }

            _SystemState = hb.system_status;

            var newMode = hb.custom_mode;
            if (_ModeCode != newMode)
            {
                _ModeCode = hb.custom_mode;
            }
            return true;
        }

        protected bool ProcessMessage_SYS_STATUS(MAVLinkMessage msg)
        {
            var sysstatus = (mavlink_sys_status_t)msg.data;

            SystemInfo.Load = sysstatus.load / 10.0f;

            _PowerInfo.BatteryRemaining = sysstatus.battery_remaining;
            _PowerInfo.Current = sysstatus.current_battery / 100.0f;

            SystemInfo.PacketDropRemote = sysstatus.drop_rate_comm;
            
            SystemInfo.ErrorCount[0] = sysstatus.errors_count1;
            SystemInfo.ErrorCount[1] = sysstatus.errors_count2;
            SystemInfo.ErrorCount[2] = sysstatus.errors_count3;
            SystemInfo.ErrorCount[3] = sysstatus.errors_count4;

            SystemInfo.Sensors.ValueEnabled = sysstatus.onboard_control_sensors_enabled;
            SystemInfo.Sensors.ValueHealth = sysstatus.onboard_control_sensors_health;
            SystemInfo.Sensors.ValuePresent = sysstatus.onboard_control_sensors_present;

            if (SystemInfo.ErrorCount[0] > 0 || SystemInfo.ErrorCount[1] > 0)
            {
                //messageHigh = "InternalError 0x" + (errors_count1 + (errors_count2 << 16)).ToString("X");
                //SystemInfoReceived?.Invoke(this, $"内部错误：0x{((UInt32)SystemInfo.ErrorCount[0] + (((UInt32)SystemInfo.ErrorCount[1]) << 16)).ToString("X")}", MAV_SEVERITY.ERROR);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, $"内部错误：0x{((UInt32)SystemInfo.ErrorCount[0] + (((UInt32)SystemInfo.ErrorCount[1]) << 16)).ToString("X")}"));
            }

            if ((!SystemInfo.Sensors.PrearmHealth) && SystemInfo.Sensors.PrearmEnabled && SystemInfo.Sensors.PrearmPresent)
            {
                //string text = messages.LastOrDefault(a => a.message.ToLower().Contains("prearm")).message
                //    ?.ToString();
                //SystemInfoReceived?.Invoke(this, text, MAV_SEVERITY.ERROR);
                messages.Add((DateTime.Now, MAV_SEVERITY.INFO, "无法解锁"));
            }
            if (!SystemInfo.Sensors.GpsHealth && SystemInfo.Sensors.GpsEnabled && SystemInfo.Sensors.GpsPresent)
            {
                //SystemInfoReceived?.Invoke(this, "GPS 信号差", MAV_SEVERITY.CRITICAL);
                messages.Add((DateTime.Now, MAV_SEVERITY.CRITICAL, "GPS 信号差"));
            }
            if (!SystemInfo.Sensors.GyroHealth && SystemInfo.Sensors.GyroEnabled && SystemInfo.Sensors.GyroPresent)
            {
                //SystemInfoReceived?.Invoke(this, "陀螺仪数据异常", MAV_SEVERITY.CRITICAL);
                messages.Add((DateTime.Now, MAV_SEVERITY.CRITICAL, "陀螺仪数据异常"));
            }
            if (!SystemInfo.Sensors.AccelerometerHealth && SystemInfo.Sensors.AccelerometerEnabled && SystemInfo.Sensors.AccelerometerPresent)
            {
                //SystemInfoReceived?.Invoke(this, "加速度计数据异常", MAV_SEVERITY.CRITICAL);
                messages.Add((DateTime.Now, MAV_SEVERITY.CRITICAL, "加速度计数据异常"));
            }
            if (!SystemInfo.Sensors.CompassHealth && SystemInfo.Sensors.CompassEnabled && SystemInfo.Sensors.CompassPresent)
            {
                //SystemInfoReceived?.Invoke(this, "罗盘数据异常", MAV_SEVERITY.CRITICAL);
                messages.Add((DateTime.Now, MAV_SEVERITY.CRITICAL, "罗盘数据异常"));
            }
            if (!SystemInfo.Sensors.BarometerHealth && SystemInfo.Sensors.BarometerEnabled && SystemInfo.Sensors.BarometerPresent)
            {
                //SystemInfoReceived?.Invoke(this, "高度计数据异常", MAV_SEVERITY.CRITICAL);
                messages.Add((DateTime.Now, MAV_SEVERITY.CRITICAL, "高度计数据异常"));
            }
            if (!SystemInfo.Sensors.LaserPositionHealth && SystemInfo.Sensors.LaserPositionEnabled && SystemInfo.Sensors.LaserPositionPresent)
            {
                //SystemInfoReceived?.Invoke(this, "LiDar数据异常", MAV_SEVERITY.ERROR);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, "LiDar 数据异常"));
            }
            if (!SystemInfo.Sensors.OpticalFlowHealth && SystemInfo.Sensors.OpticalFlowEnabled && SystemInfo.Sensors.OpticalFlowPresent)
            {
                //SystemInfoReceived?.Invoke(this, "光流数据异常", MAV_SEVERITY.ERROR);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, "光流数据异常"));
            }
            if (!SystemInfo.Sensors.VisionPositionNHealth && SystemInfo.Sensors.VisionPositionNEnabled && SystemInfo.Sensors.VisionPositionNPresent)
            {
                //SystemInfoReceived?.Invoke(this, "视觉数据异常", MAV_SEVERITY.ERROR);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, "视觉数据异常"));
            }
            if (!SystemInfo.Sensors.TerrainHealth && SystemInfo.Sensors.TerrainEnabled && SystemInfo.Sensors.TerrainPresent)
            {
                //SystemInfoReceived?.Invoke(this, "地形数据异常", MAV_SEVERITY.ERROR);
                messages.Add((DateTime.Now, MAV_SEVERITY.WARNING, "地形数据异常"));
            }
            if (!SystemInfo.Sensors.GeofenceHealth && SystemInfo.Sensors.GeofenceEnabled && SystemInfo.Sensors.GeofencePresent)
            {
                //SystemInfoReceived?.Invoke(this, "地理围栏数据异常", MAV_SEVERITY.ERROR);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, "地理围栏数据异常"));
            }
            if (!SystemInfo.Sensors.AhrsHealth && SystemInfo.Sensors.AhrsEnabled && SystemInfo.Sensors.AhrsPresent)
            {
                //SystemInfoReceived?.Invoke(this, "航姿数据异常", MAV_SEVERITY.CRITICAL);
                messages.Add((DateTime.Now, MAV_SEVERITY.CRITICAL, "航姿数据异常"));
            }

            if(SystemInfo.Sensors.RcReceiverPresent)
            {
                if(SystemInfo.Sensors.RcReceiverEnabled)
                {
                    if (!SystemInfo.Sensors.RcReceiverHealth)
                    {
                        messages.Add((DateTime.Now, MAV_SEVERITY.CRITICAL, "遥控接收机异常"));
                    }
                }
                else
                {
                    messages.Add((DateTime.Now, MAV_SEVERITY.WARNING, "遥控接收机禁用"));
                }
            }
            else
            {
                if (SystemInfo.Sensors.RcReceiverEnabled)
                {
                    messages.Add((DateTime.Now, MAV_SEVERITY.CRITICAL, "没有找到遥控接收机"));
                }
            }

            if (!SystemInfo.Sensors.BatteryHealth && SystemInfo.Sensors.BatteryEnabled && SystemInfo.Sensors.BatteryPresent)
            {
                //SystemInfoReceived?.Invoke(this, "电池异常", MAV_SEVERITY.ERROR);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, "电池异常"));
            }
            if (!SystemInfo.Sensors.ProximityHealth && SystemInfo.Sensors.ProximityEnabled && SystemInfo.Sensors.ProximityPresent)
            {
                //SystemInfoReceived?.Invoke(this, "Proximity 异常", MAV_SEVERITY.ERROR);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, "Proximity 异常"));
            }
            if (!SystemInfo.Sensors.SatcomHealth && SystemInfo.Sensors.SatcomEnabled && SystemInfo.Sensors.SatcomPresent)
            {
                //SystemInfoReceived?.Invoke(this, "卫星通信异常", MAV_SEVERITY.ERROR);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, "卫星通信异常"));
            }
            if (!SystemInfo.Sensors.DifferentialPressureHealth && SystemInfo.Sensors.DifferentialPressureEnabled && SystemInfo.Sensors.DifferentialPressurePresent)
            {
                //SystemInfoReceived?.Invoke(this, "空速数据异常", MAV_SEVERITY.ERROR);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, "空速数据异常"));
            }

            return true;
        }

        protected bool ProcessMessage_STATUSTEXT(MAVLinkMessage msg)
        {
            mavlink_statustext_t statusText = (mavlink_statustext_t)msg.data;

            MAV_SEVERITY sev = (MAV_SEVERITY)statusText.severity;
            string logdata = Encoding.UTF8.GetString(statusText.text);
            int ind = logdata.IndexOf('\0');
            if (ind != -1)
                logdata = logdata.Substring(0, ind);

            string text = logdata.Trim(_TrimChars);

            if (text.ToLower().StartsWith("prearm"))
            {
                if (text.Equals("PreArm: 3D Accel calibration needed"))
                {
                    text = "加速度计需要重新校准";
                }
                else
                {
                }
            }

            messages.Add((DateTime.Now, sev, text));
            while (messages.Count > 1000)
                messages.RemoveAt(0);

            return true;
        }

        protected bool ProcessMessage_ATTITUDE(MAVLinkMessage msg)
        {
            var att = (mavlink_attitude_t)msg.data;
            _Attitude.Roll = att.roll;
            _Attitude.Pitch = att.pitch;
            _Attitude.Yaw = att.yaw;
            
            return true;
        }

        protected bool ProcessMessage_SYSTEM_TIME(MAVLinkMessage msg)
        {
            var systime = (mavlink_system_time_t)msg.data;

            var time = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            try
            {
                time = time.AddMilliseconds(systime.time_unix_usec / 1000);

                GpsTime = time;
            }
            catch
            {
            }

            return true;
        }

        protected bool ProcessMessage_PING(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_CHANGE_OPERATOR_CONTROL(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_CHANGE_OPERATOR_CONTROL_ACK(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_AUTH_KEY(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_LINK_NODE_STATUS(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SET_MODE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_PARAM_REQUEST_READ(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_PARAM_REQUEST_LIST(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_PARAM_VALUE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_PARAM_SET(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_GPS_RAW_INT(MAVLinkMessage msg)
        {
            var gps = (mavlink_gps_raw_int_t)msg.data;
            if (!UseLocation)
            {
                if (gps.lat != int.MaxValue)
                    _PositionLatLngAlt.Lat = gps.lat * 1.0e-7;
                if (gps.lon != int.MaxValue)
                    _PositionLatLngAlt.Lng = gps.lon * 1.0e-7;

                _PositionLatLngAlt.AltitudeAbsolute = gps.alt / 1000.0f;
                // alt = gps.alt; // using vfr as includes baro calc
            }

            _GpsInfo.GpsFixType = (GPS_FIX_TYPE)gps.fix_type;
            //                    Console.WriteLine("gpsfix {0}",gpsstatus);

            if (gps.eph != ushort.MaxValue)
                _GpsInfo.HDOP = (float)Math.Round(gps.eph / 100.0, 2);

            if (gps.satellites_visible != byte.MaxValue)
                _GpsInfo.SatCount = gps.satellites_visible;

            if (gps.vel != ushort.MaxValue)
                _SpeedInfo.GroundSpeed[0] = gps.vel * 1.0e-2f;

            if (_SpeedInfo.GroundSpeed[0] > 0.5 && gps.cog != ushort.MaxValue)
                _SpeedInfo.Course[0] = gps.cog * 1.0e-2f;

            if (this.MavlinkVersion == 2)
            {
                _GpsInfo.HAcc = gps.h_acc / 1000.0f;
                _GpsInfo.VAcc = gps.v_acc / 1000.0f;
                _GpsInfo.VelAcc = gps.vel_acc / 1000.0f;
                _GpsInfo.HdgAcc = gps.hdg_acc / 1e5f;
                _GpsInfo.Yaw = gps.yaw / 100.0f;
            }
            else
            {
                _GpsInfo.HAcc = -1;
                _GpsInfo.VAcc = -1;
                _GpsInfo.VelAcc = -1;
                _GpsInfo.HdgAcc = -1;
                _GpsInfo.Yaw = -1;
            }

            return true;
        }

        protected bool ProcessMessage_GPS_STATUS(MAVLinkMessage msg)
        {
            var gps = (mavlink_gps_status_t)msg.data;
            _GpsInfo.SatCount = gps.satellites_visible;
            
            return true;
        }

        protected bool ProcessMessage_SCALED_IMU(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_RAW_IMU(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_RAW_PRESSURE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SCALED_PRESSURE(MAVLinkMessage msg)
        {
            var pres = (mavlink_scaled_pressure_t)msg.data;
            PressureInfo.AbsolutePressure = pres.press_abs;
            PressureInfo.Temperature = pres.temperature;

            return true;
        }

        protected bool ProcessMessage_ATTITUDE_QUATERNION(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_LOCAL_POSITION_NED(MAVLinkMessage msg)
        {
            mavlink_local_position_ned_t payload = (mavlink_local_position_ned_t)msg.data;
            PositionNed.X = payload.x;
            PositionNed.Y = payload.y;
            PositionNed.Z = payload.z;

            return true;
        }

        private DateTime _LastAltitudeTime = DateTime.Now;
        private float _LastAltitude = 0.0f;
        bool UseLocation;
        protected bool ProcessMessage_GLOBAL_POSITION_INT(MAVLinkMessage msg)
        {
            var loc = (mavlink_global_position_int_t)msg.data;
            // the new arhs deadreckoning may send 0 alt and 0 long. check for and undo
            _PositionLatLngAlt.Alt = loc.relative_alt / 1000.0;

            if (_LastAltitude != _PositionLatLngAlt.Alt)
            {
                if (this is Plane)
                {
                    DateTime now = DateTime.Now;
                    _SpeedInfo.VerticalSpeed = (float)((_PositionLatLngAlt.Alt - _LastAltitude) / now.Subtract(_LastAltitudeTime).TotalSeconds);
                    _LastAltitudeTime = now;
                    _LastAltitude = (float)_PositionLatLngAlt.Alt;
                }
            }

            UseLocation = true;
            if (loc.lat == 0 || loc.lon == 0 || loc.lat == int.MaxValue || loc.lon == int.MaxValue)
            {
                UseLocation = false;
            }
            else
            {
                _PositionLatLngAlt.Lat = loc.lat / 10000000.0;
                _PositionLatLngAlt.Lng = loc.lon / 10000000.0;

                _PositionLatLngAlt.AltitudeAbsolute = loc.alt / 1000.0f;

                //SpeedInfo

                _SpeedInfo.Vx[0] = loc.vx * 0.01f;
                _SpeedInfo.Vy[0] = loc.vy * 0.01f;
                _SpeedInfo.Vz[0] = loc.vz * 0.01f;
            }

            return true;
        }

        protected bool ProcessMessage_RC_CHANNELS_SCALED(MAVLinkMessage msg)
        {
            mavlink_rc_channels_scaled_t payload = (mavlink_rc_channels_scaled_t)msg.data;
            RC_Channels[1] = payload.chan1_scaled;
            RC_Channels[2] = payload.chan2_scaled;
            RC_Channels[3] = payload.chan3_scaled;
            RC_Channels[4] = payload.chan4_scaled;
            RC_Channels[5] = payload.chan5_scaled;
            RC_Channels[6] = payload.chan6_scaled;
            RC_Channels[7] = payload.chan7_scaled;
            RC_Channels[8] = payload.chan8_scaled;

            return true;
        }

        protected bool ProcessMessage_RC_CHANNELS_RAW(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SERVO_OUTPUT_RAW(MAVLinkMessage msg)
        {
            mavlink_servo_output_raw_t payload = (mavlink_servo_output_raw_t)msg.data;
            if(payload.port==0)
            {// MAIN
                ServoMain.RawValue[1] = payload.servo1_raw;
                ServoMain.RawValue[2] = payload.servo2_raw;
                ServoMain.RawValue[3] = payload.servo3_raw;
                ServoMain.RawValue[4] = payload.servo4_raw;
                ServoMain.RawValue[5] = payload.servo5_raw;
                ServoMain.RawValue[6] = payload.servo6_raw;
                ServoMain.RawValue[7] = payload.servo7_raw;
                ServoMain.RawValue[8] = payload.servo8_raw;
                ServoMain.RawValue[9] = payload.servo9_raw;
                ServoMain.RawValue[10] = payload.servo10_raw;
                ServoMain.RawValue[11] = payload.servo11_raw;
                ServoMain.RawValue[12] = payload.servo12_raw;
                ServoMain.RawValue[13] = payload.servo13_raw;
                ServoMain.RawValue[14] = payload.servo14_raw;
                ServoMain.RawValue[15] = payload.servo15_raw;
                ServoMain.RawValue[16] = payload.servo16_raw;
                //Console.WriteLine($"CH5:{payload.servo5_raw}");
            }
            else if(payload.port==1)
            {// AUX
                ServoAux.RawValue[1] = payload.servo1_raw;
                ServoAux.RawValue[2] = payload.servo2_raw;
                ServoAux.RawValue[3] = payload.servo3_raw;
                ServoAux.RawValue[4] = payload.servo4_raw;
                ServoAux.RawValue[5] = payload.servo5_raw;
                ServoAux.RawValue[6] = payload.servo6_raw;
                ServoAux.RawValue[7] = payload.servo7_raw;
                ServoAux.RawValue[8] = payload.servo8_raw;
                ServoAux.RawValue[9] = payload.servo9_raw;
                ServoAux.RawValue[10] = payload.servo10_raw;
                ServoAux.RawValue[11] = payload.servo11_raw;
                ServoAux.RawValue[12] = payload.servo12_raw;
                ServoAux.RawValue[13] = payload.servo13_raw;
                ServoAux.RawValue[14] = payload.servo14_raw;
                ServoAux.RawValue[15] = payload.servo15_raw;
                ServoAux.RawValue[16] = payload.servo16_raw;
            }

            return true;
        }

        protected bool ProcessMessage_MISSION_REQUEST_PARTIAL_LIST(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MISSION_WRITE_PARTIAL_LIST(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MISSION_ITEM(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MISSION_REQUEST(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MISSION_SET_CURRENT(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MISSION_CURRENT(MAVLinkMessage msg)
        {
            var wpcur = (mavlink_mission_current_t)msg.data;
            var newWp = wpcur.seq;
            if (newWp != CurrentWaypoint)
            {
                CurrentWaypoint = newWp;
                Console.WriteLine($"CurrentWaypoint:{CurrentWaypoint}");
                WaypointChanged?.Invoke(this, newWp);
            }

            return true;
        }

        protected bool ProcessMessage_MISSION_REQUEST_LIST(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MISSION_COUNT(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MISSION_CLEAR_ALL(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MISSION_ITEM_REACHED(MAVLinkMessage msg)
        {
            mavlink_mission_item_reached_t missionItemReached = (mavlink_mission_item_reached_t)msg.data;
            MissionItemReached?.Invoke(this, missionItemReached.seq);
            this.ReachedWaypoint = missionItemReached.seq;
            //Console.WriteLine($"到达航点:{missionItemReached.seq}");

            return true;
        }

        protected bool ProcessMessage_MISSION_ACK(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SET_GPS_GLOBAL_ORIGIN(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_GPS_GLOBAL_ORIGIN(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_PARAM_MAP_RC(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MISSION_REQUEST_INT(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SAFETY_SET_ALLOWED_AREA(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SAFETY_ALLOWED_AREA(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_ATTITUDE_QUATERNION_COV(MAVLinkMessage msg)
        {
            return true;
        }

        bool _GuidedWpArrived = false;
        protected bool ProcessMessage_NAV_CONTROLLER_OUTPUT(MAVLinkMessage msg)
        {
            var nav = (mavlink_nav_controller_output_t)msg.data;
            _NavigationInfo.DesiredRollDegree = nav.nav_roll;
            _NavigationInfo.DesiredPitchDegree = nav.nav_pitch;
            _NavigationInfo.DesiredHeadingDegree = nav.nav_bearing;
            _NavigationInfo.TargetHeadingDegree = nav.target_bearing;
            _NavigationInfo.WaypointDistance = nav.wp_dist;
            _NavigationInfo.AltitudeError = nav.alt_error;
            _NavigationInfo.AirspeedError = nav.aspd_error;
            _NavigationInfo.CrossTrackError = nav.xtrack_error;

            if (nav.wp_dist > 0)
                _GuidedWpArrived = false;
            else
            {
                if(_GuidedWpArrived==false)
                {
                    _GuidedWpArrived = true;

                    if (this.ModeCode == (UInt32)PLANE_MODE.GUIDED || this.ModeCode == (UInt32)COPTER_MODE.GUIDED || this.ModeCode == (UInt32)ROVER_MODE.GUIDED)
                    {
                        GuidedWaypointArrived?.Invoke(this);
                    }
                }
            }

            return true;
        }

        protected bool ProcessMessage_GLOBAL_POSITION_INT_COV(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_LOCAL_POSITION_NED_COV(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_RC_CHANNELS(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_REQUEST_DATA_STREAM(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_DATA_STREAM(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MANUAL_CONTROL(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_RC_CHANNELS_OVERRIDE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MISSION_ITEM_INT(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_VFR_HUD(MAVLinkMessage msg)
        {
            mavlink_vfr_hud_t vfrHud = (mavlink_vfr_hud_t)msg.data;
            _SpeedInfo.AirSpeed = vfrHud.airspeed;
            _SpeedInfo.GroundSpeed[0] = vfrHud.groundspeed;
            Throttle = vfrHud.throttle;

            return true;
        }

        protected bool ProcessMessage_COMMAND_INT(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_COMMAND_LONG(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_COMMAND_ACK(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_COMMAND_CANCEL(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MANUAL_SETPOINT(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SET_ATTITUDE_TARGET(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_ATTITUDE_TARGET(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SET_POSITION_TARGET_LOCAL_NED(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_POSITION_TARGET_LOCAL_NED(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SET_POSITION_TARGET_GLOBAL_INT(MAVLinkMessage msg)
        {
            mavlink_position_target_global_int_t payload = (mavlink_position_target_global_int_t)msg.data;
            if (payload.coordinate_frame == (byte)MAVLink.MAV_FRAME.GLOBAL_INT)
            {
                TargetLocation = new PointLatLngAlt(payload.lat_int / 1e7, payload.lon_int / 1e7,
                                    payload.alt,
                                    payload.type_mask.ToString());

                if (payload.coordinate_frame == (byte)MAVLink.MAV_FRAME.GLOBAL_RELATIVE_ALT)
                    TargetLocation = new PointLatLngAlt(payload.lat_int / 1e7, payload.lon_int / 1e7,
                        payload.alt + HomeLocation.Alt,
                        payload.type_mask.ToString());
            }

            return true;
        }

        protected bool ProcessMessage_POSITION_TARGET_GLOBAL_INT(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_HIL_STATE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_HIL_CONTROLS(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_HIL_RC_INPUTS_RAW(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_HIL_ACTUATOR_CONTROLS(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_OPTICAL_FLOW(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_GLOBAL_VISION_POSITION_ESTIMATE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_VISION_POSITION_ESTIMATE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_VISION_SPEED_ESTIMATE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_VICON_POSITION_ESTIMATE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_HIGHRES_IMU(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_OPTICAL_FLOW_RAD(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_HIL_SENSOR(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SIM_STATE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_RADIO_STATUS(MAVLinkMessage msg)
        {
            var radio = (mavlink_radio_status_t)msg.data;
            RadioInfo.RSSI = radio.rssi;
            RadioInfo.RemoteRSSI = radio.remrssi;
            RadioInfo.TxBuffer = radio.txbuf;
            RadioInfo.RxErrors = radio.rxerrors;
            RadioInfo.Noise = radio.noise;
            RadioInfo.RemoteNoise = radio.remnoise;
            RadioInfo.FixedPacketCount = radio.@fixed;

            return true;
        }

        protected bool ProcessMessage_TIMESYNC(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_CAMERA_TRIGGER(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_HIL_GPS(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_HIL_OPTICAL_FLOW(MAVLinkMessage msg)
        {
            var optflow = (mavlink_optical_flow_t)msg.data;

            OpticalFlow_m_X = optflow.flow_comp_m_x;
            OpticalFlow_m_Y = optflow.flow_comp_m_y;
            OpticalFlow_X = optflow.flow_x;
            OpticalFlow_Y = optflow.flow_y;
            OpticalFlowQuality = optflow.quality;

            return true;
        }

        protected bool ProcessMessage_HIL_STATE_QUATERNION(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SCALED_IMU2(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_LOG_REQUEST_LIST(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_LOG_ENTRY(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_LOG_REQUEST_DATA(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_LOG_DATA(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_LOG_ERASE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_LOG_REQUEST_END(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_GPS_INJECT_DATA(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GPS2_RAW(MAVLinkMessage msg)
        {
            var gps = (mavlink_gps2_raw_t)msg.data;


            if (gps.lat != int.MaxValue)
                _PositionLatLngAlt2.Lat = gps.lat * 1.0e-7;
            if (gps.lon != int.MaxValue)
                _PositionLatLngAlt2.Lng = gps.lon * 1.0e-7;

            _PositionLatLngAlt2.AltitudeAbsolute = gps.alt / 1000.0f;



            _GpsInfo2.GpsFixType = (GPS_FIX_TYPE)gps.fix_type;
            //                    Console.WriteLine("gpsfix {0}",gpsstatus);

            if (gps.eph != ushort.MaxValue)
                _GpsInfo.HDOP2 = (float)Math.Round(gps.eph / 100.0, 2);

            if (gps.satellites_visible != byte.MaxValue)
                _GpsInfo.SatCount2 = gps.satellites_visible;

            if (gps.vel != ushort.MaxValue)
                _SpeedInfo.GroundSpeed[1] = gps.vel * 1.0e-2f;

            if (_SpeedInfo.GroundSpeed[1] > 0.5 && gps.cog != ushort.MaxValue)
                _SpeedInfo.Course[1] = gps.cog * 1.0e-2f;

            if (this.MavlinkVersion == 2)
            {
                _GpsInfo.HAcc2 = gps.h_acc / 1000.0f;
                _GpsInfo.VAcc2 = gps.v_acc / 1000.0f;
                _GpsInfo.VelAcc2 = gps.vel_acc / 1000.0f;
                _GpsInfo.HdgAcc2 = gps.hdg_acc / 1e5f;
                _GpsInfo.Yaw2 = gps.yaw / 100.0f;
            }
            else
            {
                _GpsInfo.HAcc2 = -1;
                _GpsInfo.VAcc2 = -1;
                _GpsInfo.VelAcc2 = -1;
                _GpsInfo.HdgAcc2 = -1;
                _GpsInfo.Yaw2 = -1;
            }

            return true;
        }

        protected bool ProcessMessage_POWER_STATUS(MAVLinkMessage msg)
        {
            var power = (mavlink_power_status_t)msg.data;
            _PowerInfo.BoardVoltage = power.Vcc;
            _PowerInfo.ServoVoltage = power.Vservo;

            try
            {
                _PowerInfo.VoltageFlag = (MAV_POWER_STATUS)power.flags;

                if (_PowerInfo.VoltageFlag == MAVLink.MAV_POWER_STATUS.PERIPH_OVERCURRENT)
                {
                    //messageHigh = "PERIPH_OVERCURRENT";
                    //SystemInfoReceived?.Invoke(this, "外设电流过大", MAV_SEVERITY.WARNING);
                    messages.Add((DateTime.Now, MAV_SEVERITY.WARNING, "外设电流过大"));
                }
                else if (_PowerInfo.VoltageFlag == MAV_POWER_STATUS.PERIPH_HIPOWER_OVERCURRENT)
                {
                    //messageHigh = "PERIPH_HIPOWER_OVERCURRENT";
                    //SystemInfoReceived?.Invoke(this, "外设电流过大", MAV_SEVERITY.WARNING);
                    messages.Add((DateTime.Now, MAV_SEVERITY.WARNING, "外设电流过大"));
                }
            }
            catch
            {
            }

            return true;
        }

        protected bool ProcessMessage_SERIAL_CONTROL(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_GPS_RTK(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_GPS2_RTK(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SCALED_IMU3(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_DATA_TRANSMISSION_HANDSHAKE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_ENCAPSULATED_DATA(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_DISTANCE_SENSOR(MAVLinkMessage msg)
        {
            var sonar = (mavlink_distance_sensor_t)msg.data;
            RangeFinders[sonar.id].CurrentDistance = sonar.current_distance;

            return true;
        }

        protected bool ProcessMessage_TERRAIN_REQUEST(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_TERRAIN_DATA(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_TERRAIN_CHECK(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_TERRAIN_REPORT(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SCALED_PRESSURE2(MAVLinkMessage msg)
        {
            var pres = (mavlink_scaled_pressure2_t)msg.data;
            PressureInfo.AbsolutePressure2 = pres.press_abs;
            PressureInfo.Temperature2 = pres.temperature;

            return true;
        }

        protected bool ProcessMessage_ATT_POS_MOCAP(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SET_ACTUATOR_CONTROL_TARGET(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_ACTUATOR_CONTROL_TARGET(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_ALTITUDE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_RESOURCE_REQUEST(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SCALED_PRESSURE3(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_FOLLOW_TARGET(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_CONTROL_SYSTEM_STATE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_BATTERY_STATUS(MAVLinkMessage msg)
        {
            var bats = (mavlink_battery_status_t)msg.data;
            double temp_battery_voltage = bats.voltages.Sum(a => a != ushort.MaxValue ? a / 1000.0 : 0) + bats.voltages_ext.Sum(a => a != ushort.MaxValue ? a / 1000.0 : 0);
            BatteryInfo bat = _PowerInfo.BatteryInfo;
            if (bats.id == 0)
            {
                if (bats.voltages[0] != UInt16.MaxValue)
                {
                    bat.Cells[0] = bats.voltages[0] / 1000.0f;
                    if (bats.voltages[1] != ushort.MaxValue) bat.Cells[1] = bats.voltages[1] / 1000.0f;
                    else bat.Cells[1] = 0.0f;
                    if (bats.voltages[2] != ushort.MaxValue) bat.Cells[2] = bats.voltages[2] / 1000.0f;
                    else bat.Cells[2] = 0.0f;
                    if (bats.voltages[3] != ushort.MaxValue) bat.Cells[3] = bats.voltages[3] / 1000.0f;
                    else bat.Cells[3] = 0.0f;
                    if (bats.voltages[4] != ushort.MaxValue) bat.Cells[4] = bats.voltages[4] / 1000.0f;
                    else bat.Cells[4] = 0.0f;
                    if (bats.voltages[5] != ushort.MaxValue) bat.Cells[5] = bats.voltages[5] / 1000.0f;
                    else bat.Cells[5] = 0.0f;
                    if (bats.voltages[6] != ushort.MaxValue) bat.Cells[6] = bats.voltages[6] / 1000.0f;
                    else bat.Cells[6] = 0.0f;
                    if (bats.voltages[7] != ushort.MaxValue) bat.Cells[7] = bats.voltages[7] / 1000.0f;
                    else bat.Cells[7] = 0.0f;
                    if (bats.voltages[8] != ushort.MaxValue) bat.Cells[8] = bats.voltages[8] / 1000.0f;
                    else bat.Cells[8] = 0.0f;
                    if (bats.voltages[9] != ushort.MaxValue) bat.Cells[9] = bats.voltages[9] / 1000.0f;
                    else bat.Cells[9] = 0.0f;
                    if (bats.voltages_ext[0] != ushort.MaxValue) bat.Cells[10] = bats.voltages_ext[0] / 1000.0f;
                    else bat.Cells[10] = 0.0f;
                    if (bats.voltages_ext[1] != ushort.MaxValue) bat.Cells[11] = bats.voltages_ext[1] / 1000.0f;
                    else bat.Cells[11] = 0.0f;
                    if (bats.voltages_ext[2] != ushort.MaxValue) bat.Cells[12] = bats.voltages_ext[2] / 1000.0f;
                    else bat.Cells[12] = 0.0f;
                    if (bats.voltages_ext[3] != ushort.MaxValue) bat.Cells[13] = bats.voltages_ext[3] / 1000.0f;
                    else bat.Cells[13] = 0.0f;
                }
            }
            bat.UsedmAh[bats.id] = bats.current_consumed;
            bat.Remaining[bats.id] = bats.battery_remaining;
            bat.Voltage[bats.id] = (float)temp_battery_voltage;
            bat.Current[bats.id] = bats.current_battery / 100.0f;
            if (bats.temperature != short.MaxValue)
                bat.Temperature[bats.id] = bats.temperature / 100.0f;
            bat.RemainMinute[bats.id] = bats.time_remaining / 60.0f;

            return true;
        }

        protected bool ProcessMessage_AUTOPILOT_VERSION(MAVLinkMessage msg)
        {
            mavlink_autopilot_version_t version = (mavlink_autopilot_version_t)msg.data;
            var main = (byte)(version.flight_sw_version >> 24);
            var sub = (byte)((version.flight_sw_version >> 16) & 0xff);
            var rev = (byte)((version.flight_sw_version >> 8) & 0xff);
            var type =
                (MAVLink.FIRMWARE_VERSION_TYPE)(version.flight_sw_version & 0xff);

            this.Version = new Version(main, sub, rev, (int)type);

            this.UID = version.uid;
            this.UIDStr = String.Join("-", version.uid2.Select(b => b.ToString("X2")));

            try
            {
                this.Capabilities = (MAVLink.MAV_PROTOCOL_CAPABILITY)version.capabilities;
                var test = (MAVLink.MAV_PROTOCOL_CAPABILITY)version.capabilities;

                Console.WriteLine(test);
            }
            catch
            {
            }

            //Debug.Write("Flight SW Version: ");
            //Debug.WriteLine(version.flight_sw_version);
            //Debug.Write("Middleware SW: ");
            //Debug.WriteLine(version.middleware_sw_version);
            //Debug.Write("OS Custom: ");
            //Debug.WriteLine(version.os_custom_version);
            //Debug.Write("OS SW: ");
            //Debug.WriteLine(version.os_sw_version);
            //Debug.Write("board_version: ");
            //Debug.WriteLine(version.board_version);
            //Debug.Write("Vendor ID: ");
            //Debug.WriteLine(version.vendor_id);
            //Debug.Write("Product ID: ");
            //Debug.WriteLine(version.product_id);
            //Debug.Write("Board Version: ");
            //Debug.WriteLine(version.board_version);

            return true;
        }

        protected bool ProcessMessage_LANDING_TARGET(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SENSOR_OFFSETS(MAVLinkMessage msg)
        {
            var sensofs = (mavlink_sensor_offsets_t)msg.data;
            SystemInfo.Sensors.MagOffsetX = sensofs.mag_ofs_x;
            SystemInfo.Sensors.MagOffsetY = sensofs.mag_ofs_y;
            SystemInfo.Sensors.MagOffsetZ = sensofs.mag_ofs_z;
            SystemInfo.Sensors.MagDeclination = sensofs.mag_declination;

            SystemInfo.Sensors.RawPressure = sensofs.raw_press;
            SystemInfo.Sensors.RawTemperature = sensofs.raw_temp;

            SystemInfo.Sensors.GyroCalX = sensofs.gyro_cal_x;
            SystemInfo.Sensors.GyroCalY = sensofs.gyro_cal_y;
            SystemInfo.Sensors.GyroCalZ = sensofs.gyro_cal_z;

            SystemInfo.Sensors.AccelCalX = sensofs.accel_cal_x;
            SystemInfo.Sensors.AccelCalY = sensofs.accel_cal_y;
            SystemInfo.Sensors.AccelCalZ = sensofs.accel_cal_z;

            return true;
        }

        protected bool ProcessMessage_SET_MAG_OFFSETS(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MEMINFO(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_AP_ADC(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_DIGICAM_CONFIGURE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_DIGICAM_CONTROL(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MOUNT_CONFIGURE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MOUNT_CONTROL(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_MOUNT_STATUS(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_FENCE_POINT(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_FENCE_FETCH_POINT(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_FENCE_STATUS(MAVLinkMessage msg)
        {
            var fence = (mavlink_fence_status_t)msg.data;

            this.FenceBreachType = (FENCE_BREACH)fence.breach_type;
            //fenceb_status = (MAVLink.fence)fence.breach_status;
            //fenceb_count = fence.breach_count;


            if (fence.breach_status != 0)
            {
                // fence breached
                //messageHigh = "Fence Breach " + (MAVLink.FENCE_BREACH)fence.breach_type;
                //RaiseStateChanged("FenceBreachType");
            }

            return true;
        }

        protected bool ProcessMessage_AHRS(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_SIMSTATE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_HWSTATUS(MAVLinkMessage msg)
        {
            var hwstatus = (mavlink_hwstatus_t)msg.data;
            _PowerInfo.BoardVoltage = hwstatus.Vcc;

            return true;
        }

        protected bool ProcessMessage_RADIO(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_LIMITS_STATUS(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_WIND(MAVLinkMessage msg)
        {
            var wind = (mavlink_wind_t)msg.data;
            WindInfo.Valid = true;
            WindInfo.Direction = (wind.direction + 360) % 360;
            WindInfo.Velocity = wind.speed * _Multiplierspeed;

            return true;
        }

        protected bool ProcessMessage_DATA16(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_DATA32(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_DATA64(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_DATA96(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_RANGEFINDER(MAVLinkMessage msg)
        {
            var sonar = (mavlink_rangefinder_t)msg.data;
            for (byte i = 0; i < 3; i++)
            {
                RangeFinders[i].Range = sonar.distance;
                RangeFinders[i].Voltage = sonar.voltage;
            }
            return true;
        }

        protected bool ProcessMessage_AIRSPEED_AUTOCAL(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_RALLY_POINT(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_RALLY_FETCH_POINT(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_COMPASSMOT_STATUS(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_AHRS2(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_CAMERA_STATUS(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_CAMERA_FEEDBACK(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_BATTERY2(MAVLinkMessage msg)
        {
            var bat = (mavlink_battery2_t)msg.data;
            _PowerInfo.Current2 = bat.current_battery / 100.0f;
            return true;
        }

        protected bool ProcessMessage_AHRS3(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_AUTOPILOT_VERSION_REQUEST(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_REMOTE_LOG_DATA_BLOCK(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_REMOTE_LOG_BLOCK_STATUS(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_LED_CONTROL(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_MAG_CAL_PROGRESS(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_MAG_CAL_REPORT(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_EKF_STATUS_REPORT(MAVLinkMessage msg)
        {
            bool valueChanged = false;
            var ekfstatusm = (mavlink_ekf_status_report_t)msg.data;

            if (EKF.VelocityVariance != ekfstatusm.velocity_variance)
            {
                EKF.VelocityVariance = ekfstatusm.velocity_variance;
                valueChanged = true;
            }

            if (EKF.CompassVariance != ekfstatusm.compass_variance)
            {
                EKF.CompassVariance = ekfstatusm.compass_variance;
                valueChanged = true;
            }

            if (EKF.PositionHorizontalVariance != ekfstatusm.pos_horiz_variance)
            {
                EKF.PositionHorizontalVariance = ekfstatusm.pos_horiz_variance;
                valueChanged = true;
            }

            if (EKF.PositionVerticalVariance != ekfstatusm.pos_vert_variance)
            {
                EKF.PositionVerticalVariance = ekfstatusm.pos_vert_variance;
                valueChanged = true;
            }

            if (EKF.TerrainAltitudeVariance != ekfstatusm.terrain_alt_variance)
            {
                EKF.TerrainAltitudeVariance = ekfstatusm.terrain_alt_variance;
                valueChanged = true;
            }

            if (EKF.Flags != ekfstatusm.flags)
            {
                EKF.Flags = ekfstatusm.flags;
                valueChanged = true;
            }

            float oldStatus = EKF.Status;
            float status =
                Math.Max(EKF.VelocityVariance,
                    Math.Max(EKF.CompassVariance, Math.Max(EKF.PositionHorizontalVariance, Math.Max(EKF.PositionVerticalVariance, EKF.TerrainAltitudeVariance))));
            if (EKF.Status != status)
            {
                EKF.Status = status;
                valueChanged = true;
            }

            if (EKF.VelocityVariance >= 1)
            {
                //SystemInfoReceived?.Invoke(this, "速度读数异常", MAV_SEVERITY.ERROR);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, "速度读数异常"));
            }

            if (EKF.CompassVariance >= 1)
            {
                //SystemInfoReceived?.Invoke(this, "罗盘读数异常", MAV_SEVERITY.ERROR);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, "罗盘读数异常"));
            }

            if (EKF.PositionHorizontalVariance >= 1)
            {
                //SystemInfoReceived?.Invoke(this, "水平位置读数异常", MAV_SEVERITY.WARNING);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, "水平位置读数异常"));
            }

            if (EKF.PositionVerticalVariance >= 1)
            {
                //SystemInfoReceived?.Invoke(this, "位置读数异常", MAV_SEVERITY.WARNING);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, "位置读数异常"));
            }

            if (EKF.TerrainAltitudeVariance >= 1)
            {
                //SystemInfoReceived?.Invoke(this, "地形高度读数异常", MAV_SEVERITY.WARNING);
                messages.Add((DateTime.Now, MAV_SEVERITY.ERROR, "地形高度读数异常"));
            }

            for (var a = 1; a <= (int)MAVLink.EKF_STATUS_FLAGS.EKF_UNINITIALIZED; a = a << 1)
            {
                var currentbit = ekfstatusm.flags & a;
                if (currentbit == 0)
                {
                    var currentflag =
                        (MAVLink.EKF_STATUS_FLAGS)
                        Enum.Parse(typeof(MAVLink.EKF_STATUS_FLAGS), a.ToString());

                    switch (currentflag)
                    {
                        case MAVLink.EKF_STATUS_FLAGS.EKF_ATTITUDE: // step 1
                            EKF.Status = 1;
                            //log.Info("EKF red has no EKF_ATTITUDE - " + (MAVLink.EKF_STATUS_FLAGS)ekfstatusm.flags);
                            break;
                        case MAVLink.EKF_STATUS_FLAGS.EKF_VELOCITY_HORIZ: // with pos
                            if ((int)GpsFixType > 0)
                            {
                                // we have gps and dont have vel_hoz
                                EKF.Status = 1;
                                //log.Debug("EKF red has gps lock but no EKF_ATTITUDE and EKF_VELOCITY_HORIZ - " + (MAVLink.EKF_STATUS_FLAGS)ekfstatusm.flags);
                            }

                            break;
                        case MAVLink.EKF_STATUS_FLAGS.EKF_VELOCITY_VERT: // with pos
                                                                         //case MAVLink.EKF_STATUS_FLAGS.EKF_POS_HORIZ_REL: // optical flow
                        case MAVLink.EKF_STATUS_FLAGS.EKF_POS_HORIZ_ABS: // step 1
                        case MAVLink.EKF_STATUS_FLAGS.EKF_POS_VERT_ABS: // step 1
                                                                        //case MAVLink.EKF_STATUS_FLAGS.EKF_POS_VERT_AGL: //  range finder
                                                                        //case MAVLink.EKF_STATUS_FLAGS.EKF_CONST_POS_MODE:  // never true when absolute - non gps
                                                                        //case MAVLink.EKF_STATUS_FLAGS.EKF_PRED_POS_HORIZ_REL: // optical flow
                        case MAVLink.EKF_STATUS_FLAGS.EKF_PRED_POS_HORIZ_ABS: // ekf has origin - post arm
                                                                              //messageHigh = Strings.ERROR + " " + currentflag.ToString().Replace("_", " ");
                                                                              //messageHighTime = DateTime.Now;
                            break;

                    }
                }
                else
                {
                    if (a == (int)MAVLink.EKF_STATUS_FLAGS.EKF_UNINITIALIZED)
                    {
                        EKF.Status = 1;
                        Debug.WriteLine("EKF red uninit " + (MAVLink.EKF_STATUS_FLAGS)ekfstatusm.flags);
                    }
                }
            }

            if (EKF.Status != oldStatus)
            {
                valueChanged = true;
            }
            return true;
        }

        protected bool ProcessMessage_PID_TUNING(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_DEEPSTALL(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_GIMBAL_REPORT(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GIMBAL_CONTROL(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GIMBAL_TORQUE_CMD_REPORT(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GOPRO_HEARTBEAT(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GOPRO_GET_REQUEST(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GOPRO_GET_RESPONSE(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GOPRO_SET_REQUEST(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_GOPRO_SET_RESPONSE(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_EFI_STATUS(MAVLinkMessage msg)
        {
            var efi = (mavlink_efi_status_t)msg.data;
            if (efi.ecu_index == 0)
            {
                EFI.BarometricPressure = efi.barometric_pressure;
                EFI.CylinderHeadTemperature = efi.cylinder_head_temperature;
                EFI.EngineLoad = efi.engine_load;
                EFI.Health = efi.health;
                EFI.ExhastGasTemperature = efi.exhaust_gas_temperature;
                EFI.IntakeManifoldTemperature = efi.intake_manifold_temperature;
                EFI.RPM = efi.rpm;
                EFI.FuelFlow = efi.fuel_flow;
                EFI.FuelConsumed = efi.fuel_consumed;
            }
            return true;
        }

        protected bool ProcessMessage_RPM(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_ESTIMATOR_STATUS(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_WIND_COV(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GPS_INPUT(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GPS_RTCM_DATA(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_HIGH_LATENCY(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_HIGH_LATENCY2(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_VIBRATION(MAVLinkMessage msg)
        {
            var vibe = (mavlink_vibration_t)msg.data;

            Vibe.Clip0 = vibe.clipping_0;
            Vibe.Clip1 = vibe.clipping_1;
            Vibe.Clip2 = vibe.clipping_2;
            Vibe.X = vibe.vibration_x;
            Vibe.Y = vibe.vibration_y;
            Vibe.Z = vibe.vibration_z;
            return true;
        }

        protected bool ProcessMessage_HOME_POSITION(MAVLinkMessage msg)
        {
            var hp = (mavlink_home_position_t)msg.data;

            double
                lat = hp.latitude / 10000000.0f,
                lng = hp.longitude / 10000000.0f,
                alt = hp.altitude / 1000.0f;

            if (this.HomeLocation.Lat != lat || this.HomeLocation.Lng != lng || this.HomeLocation.Alt != alt)
            {
                this.HomeLocation.Lat = hp.latitude / 10000000.0f;
                this.HomeLocation.Lng = hp.longitude / 10000000.0f;
                this.HomeLocation.Alt = hp.altitude / 1000.0f;

                HomeChanged?.Invoke(this);
            }
            return true;
        }

        protected bool ProcessMessage_SET_HOME_POSITION(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_MESSAGE_INTERVAL(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_EXTENDED_SYS_STATE(MAVLinkMessage msg)
        {
            var extsysstatus = (mavlink_extended_sys_state_t)msg.data;
            SystemInfo.VTOLState = (MAV_VTOL_STATE)extsysstatus.vtol_state;
            SystemInfo.LandState = (MAV_LANDED_STATE)extsysstatus.landed_state;
            return true;
        }

        protected bool ProcessMessage_ADSB_VEHICLE(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_COLLISION(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_V2_EXTENSION(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_MEMORY_VECT(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_DEBUG_VECT(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_NAMED_VALUE_FLOAT(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_NAMED_VALUE_INT(MAVLinkMessage msg)
        {

            return true;
        }

      

        protected bool ProcessMessage_DEBUG(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_SETUP_SIGNING(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_BUTTON_CHANGE(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_PLAY_TUNE(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_CAMERA_INFORMATION(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_CAMERA_SETTINGS(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_STORAGE_INFORMATION(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_CAMERA_CAPTURE_STATUS(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_CAMERA_IMAGE_CAPTURED(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_FLIGHT_INFORMATION(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_MOUNT_ORIENTATION(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_LOGGING_DATA(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_LOGGING_DATA_ACKED(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_LOGGING_ACK(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_VIDEO_STREAM_INFORMATION(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_VIDEO_STREAM_STATUS(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_CAMERA_FOV_STATUS(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_CAMERA_TRACKING_IMAGE_STATUS(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_CAMERA_TRACKING_GEO_STATUS(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GIMBAL_MANAGER_INFORMATION(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GIMBAL_MANAGER_STATUS(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GIMBAL_MANAGER_SET_ATTITUDE(MAVLinkMessage msg)
        {
            return true;
        }

        protected bool ProcessMessage_GIMBAL_DEVICE_INFORMATION(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GIMBAL_DEVICE_SET_ATTITUDE(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_GIMBAL_DEVICE_ATTITUDE_STATUS(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_AUTOPILOT_STATE_FOR_GIMBAL_DEVICE(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_GIMBAL_MANAGER_SET_PITCHYAW(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_GIMBAL_MANAGER_SET_MANUAL_CONTROL(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_ESC_INFO(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_ESC_STATUS(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_WIFI_CONFIG_AP(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_PROTOCOL_VERSION(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_AIS_VESSEL(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_UAVCAN_NODE_STATUS(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_UAVCAN_NODE_INFO(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_PARAM_EXT_REQUEST_READ(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_PARAM_EXT_REQUEST_LIST(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_PARAM_EXT_VALUE(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_PARAM_EXT_SET(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_PARAM_EXT_ACK(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_OBSTACLE_DISTANCE(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_ODOMETRY(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_TRAJECTORY_REPRESENTATION_WAYPOINTS(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_TRAJECTORY_REPRESENTATION_BEZIER(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_CELLULAR_STATUS(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_ISBD_LINK_STATUS(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_CELLULAR_CONFIG(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_RAW_RPM(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_UTM_GLOBAL_POSITION(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_DEBUG_FLOAT_ARRAY(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_ORBIT_EXECUTION_STATUS(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_SMART_BATTERY_INFO(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_GENERATOR_STATUS(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_ACTUATOR_OUTPUT_STATUS(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_TIME_ESTIMATE_TO_TARGET(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_TUNNEL(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_CAN_FRAME(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_CANFD_FRAME(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_CAN_FILTER_MODIFY(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_ONBOARD_COMPUTER_STATUS(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_COMPONENT_INFORMATION(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_COMPONENT_METADATA(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_PLAY_TUNE_V2(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_SUPPORTED_TUNES(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_EVENT(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_CURRENT_EVENT_SEQUENCE(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_REQUEST_EVENT(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_RESPONSE_EVENT_ERROR(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_WHEEL_DISTANCE(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_WINCH_STATUS(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_UAVIONIX_ADSB_OUT_CFG(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_UAVIONIX_ADSB_OUT_DYNAMIC(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_UAVIONIX_ADSB_TRANSCEIVER_HEALTH_REPORT(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_DEVICE_OP_READ(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_DEVICE_OP_READ_REPLY(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_DEVICE_OP_WRITE(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_DEVICE_OP_WRITE_REPLY(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_ADAP_TUNING(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_VISION_POSITION_DELTA(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_AOA_SSA(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_ESC_TELEMETRY_1_TO_4(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_ESC_TELEMETRY_5_TO_8(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_ESC_TELEMETRY_9_TO_12(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_OSD_PARAM_CONFIG(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_OSD_PARAM_CONFIG_REPLY(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_OSD_PARAM_SHOW_CONFIG(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_OSD_PARAM_SHOW_CONFIG_REPLY(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_OBSTACLE_DISTANCE_3D(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_WATER_DEPTH(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_MCU_STATUS(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_OPEN_DRONE_ID_BASIC_ID(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_OPEN_DRONE_ID_LOCATION(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_OPEN_DRONE_ID_AUTHENTICATION(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_OPEN_DRONE_ID_SELF_ID(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_OPEN_DRONE_ID_SYSTEM(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_OPEN_DRONE_ID_OPERATOR_ID(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_OPEN_DRONE_ID_MESSAGE_PACK(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_OPEN_DRONE_ID_ARM_STATUS(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_OPEN_DRONE_ID_SYSTEM_UPDATE(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_HYGROMETER_SENSOR(MAVLinkMessage msg)
        {
            return true;

        }

        protected bool ProcessMessage_ICAROUS_HEARTBEAT(MAVLinkMessage msg)
        {

            return true;
        }

        protected bool ProcessMessage_ICAROUS_KINEMATIC_BANDS(MAVLinkMessage msg)
        {

            return true;
        }
    }
}
